package drds.plus.executor.cursor.column_index_mapping;

import drds.plus.executor.cursor.cursor_metadata.ColumnNameAndTableNameAndColumnIndexAndNextHolder;
import drds.plus.executor.cursor.cursor_metadata.CursorMetaData;
import drds.plus.executor.row_values.RowValues;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class ColumnIndexInTemplateCursorMetaDataToColumnIndexInRequestCursorMetaDataConvertor {
    protected CursorMetaData cursorMetaData;

    /**
     * 在每次切换了一个cursor以后，需要取第一个记录.这个标记的作用就是告诉下一次的循环是一个新的cursor了，需要拿第一个记录出来和看看是否需要做匹配。
     */
    protected boolean firstInNewCursor = true;
    /**
     * 用来统一所有MergeCursor中的index, 以第一个为模板。
     * 如果和第一个的index不匹配，那么valueMappingMap就会有一些对应关系，
     * 存放了第一个cursor中的index值和后续其他cursor的index值之间的对应关系。
     */
    private Map<Integer /* 返回列中的index位置 */, Integer /* 实际数据中的index位置 */> columnIndexInTemplateCursorMetaDataToColumnIndexInRequestCursorMetaDataMap = new HashMap<Integer, Integer>();

    public RowValues wrapAndBuildColumnIndexInTemplateCursorMetaDataToColumnIndexInRequestCursorMetaDataMapIfNeed(RowValues rowData) {
        if (!firstInNewCursor) {
            return wrap(rowData);
        } else {
            firstInNewCursor = false;
            {//构建mapping
                if (this.cursorMetaData == null) {
                    this.cursorMetaData = rowData.getParentCursorMetaData();
                }
                Iterator<ColumnNameAndTableNameAndColumnIndexAndNextHolder> iterator = this.cursorMetaData.columnNameAndTableNameAndColumnIndexAndNextHolderIterator();
                while (iterator.hasNext()) {
                    //真实请求的列信息
                    ColumnNameAndTableNameAndColumnIndexAndNextHolder columnNameAndTableNameAndColumnIndexAndNextHolder = iterator.next();//依次进行遍历
                    //游标里面的列信息
                    Integer indexInRowData = rowData.getParentCursorMetaData().getIndex(columnNameAndTableNameAndColumnIndexAndNextHolder.getTableName(), columnNameAndTableNameAndColumnIndexAndNextHolder.getColumnName(), null);
                    if (indexInRowData == null) {// return中有的数据但当前cursor中没有
                        throw new IllegalArgumentException("can't " + "find column in sub cursor : " + columnNameAndTableNameAndColumnIndexAndNextHolder.getTableName() + "." + columnNameAndTableNameAndColumnIndexAndNextHolder.getColumnName());
                    }
                    if (!indexInRowData.equals(columnNameAndTableNameAndColumnIndexAndNextHolder.getIndex())) {
                        columnIndexInTemplateCursorMetaDataToColumnIndexInRequestCursorMetaDataMap.put(columnNameAndTableNameAndColumnIndexAndNextHolder.getIndex(), indexInRowData);//根据这个映射关系 请求列到游标里面获取对应的数据
                    }
                }
            }
            return wrap(rowData);
        }

    }

    private RowValues wrap(RowValues rowData) {
        if (columnIndexInTemplateCursorMetaDataToColumnIndexInRequestCursorMetaDataMap != null && columnIndexInTemplateCursorMetaDataToColumnIndexInRequestCursorMetaDataMap.size() > 0) {
            return ColumnIndexInTemplateCursorMetaDataToColumnIndexInRequestCursorMetaDataMappingRowValues.wrap(cursorMetaData, rowData, columnIndexInTemplateCursorMetaDataToColumnIndexInRequestCursorMetaDataMap);
        } else {
            return rowData;
        }
    }


    public void reset() {
        columnIndexInTemplateCursorMetaDataToColumnIndexInRequestCursorMetaDataMap.clear();
        firstInNewCursor = true;
    }
}
